package com.tianji.learning.task;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.common.domain.query.PageQuery;
import com.tianji.learning.domain.po.PointsRecord;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsRecordService;
import com.tianji.learning.util.TableInfoContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

import static com.tianji.learning.constants.LearningConstants.POINTS_BOARD_TABLE_PREFIX;

/**
 * ClassName: PointsRecordPersistentHandler
 * Package: com.tianji.learning.task
 * Description:
 *
 * @author zr
 * Create 2024/7/31 10:53
 * Version 1.0
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class PointsRecordPersistentHandler {
    private final IPointsRecordService pointsRecordService;
    private final IPointsBoardSeasonService seasonService;

    /**
     * 定时任务创建上赛季积分明细表
     */
    @XxlJob("createPointsRecordTableJob")
    private void createPointsRecordTableOfLastSeason() {
        log.debug("开始创建上赛季积分明细表....");
        // 1.获取上月时间
        LocalDate time = LocalDate.now().minusMonths(1);
        // 2.查询赛季id
        Integer season = seasonService.querySeasonByTime(time);
        if (season == null) {
            // 赛季不存在
            return;
        }
        pointsRecordService.createPointsRecordTableBySeason(season);
        log.debug("创建上赛季积分明细表成功 ....");
    }


    /**
     * 迁移上赛季积分明细数据到上赛季积分明细表
     * XxlJob注解内容要和任务名称一致
     * 使用XxlJob实现任务分片
     */
    @XxlJob("movePointsRecord2DB")
    public void movePointsRecord2DB() {
        log.debug("开始迁移上赛季积分明细数据到赛季积分明细表...");
        // 1.获取上月时间
        LocalDate time = LocalDate.now().minusMonths(1);
        // 2.查询赛季id
        Integer season = seasonService.querySeasonByTime(time);
        if (season == null) {
            // 赛季不存在
            return;
        }
        // xxl-job分片广播
        int sharedIndex = XxlJobHelper.getShardIndex(); // 当前分片索引
        int shardTotal = XxlJobHelper.getShardTotal();  // 总分片数
        // 分页查询上赛季积分明细数据，先构建分页参数
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNo(sharedIndex + 1); // 页码
        pageQuery.setPageSize(50);    // 页面记录数
        // 3.查询积分记录数据
        while (true) {
            log.debug("当前页:{}", pageQuery.getPageNo());
            TableInfoContext.setInfo(null); // 使用默认表名，points_record
            // 按照id升序查询
            Page<PointsRecord> recordPage = pointsRecordService.lambdaQuery()
                    .le(PointsRecord::getCreateTime, time)
                    .ge(PointsRecord::getCreateTime, time)
                    .page(pageQuery.toMpPage());
            if (CollUtil.isEmpty(recordPage.getRecords())) {  // 结束循环
                break;
            }
            // 翻页，跳过N个页，N就是分片数量
            pageQuery.setPageNo(pageQuery.getPageNo() + shardTotal);   // 页码+total，跳过N页
            // 3.1.存入ThreadLocal
            TableInfoContext.setInfo(POINTS_BOARD_TABLE_PREFIX + season);
            // 持久化到db相应的赛季表中，批量新增
            pointsRecordService.saveBatch(recordPage.getRecords());
        }
        // 清空ThreadLocal中的数据
        TableInfoContext.remove();
        log.debug("完成迁移上赛季积分明细数据到赛季积分明细表...");
    }

    /**
     * 清除上赛季积分明细表的历史积分明细
     */
    @XxlJob("clearPointsRecordFromDB")
    public void clearPointsRecordFromDB() {
        log.debug("开始清除当前赛季积分明细表的历史积分明细...");
        // 1.获取上月时间
        LocalDate time = LocalDate.now().minusMonths(1);
        // 2.清理上月数据
        pointsRecordService.remove(new LambdaQueryWrapper<PointsRecord>()
                .le(PointsRecord::getCreateTime, time)
                .ge(PointsRecord::getCreateTime, time));
        log.debug("完成清除当前赛季积分明细表的历史积分明细...");
    }
}
